[Update] การส่งข้อมูลจาก EC2 ไปยัง Firehose

[Update] การส่งข้อมูลจาก EC2 ไปยัง Firehose

ครั้งนี้จะเป็นส่วนเสริมของการใช้งาน Amazon Data Firehose กับ Amazon S3 โดยในบทความนี้จะเพิ่มเนื้อหาเกี่ยวกับการใช้งาน EC2 เข้ามาด้วยครับ

ในบทความครั้งนี้จะเป็นเนื้อหาเสริมต่อจากบทความก่อนหน้านี้เกี่ยวกับการ [Update] การใช้งาน Amazon Data Firehose ร่วมกับ Amazon S3 ถ้าใครสนใจก็สามารถย้อนกลับไปดูตามลิงก์ที่แนบมาให้ได้เลย ซึ่งความแตกต่างของบทความนี้คือเราจะมีการใช้งาน EC2 ร่วมด้วย โดยจะมีการใช้งานตามรูปภาพด้านล่างนี้เลย
diagram-ec2_firehose_s3

สิ่งที่ต้องมี

สร้าง Bucket ใน Amazon S3

ก่อนอื่นต้องมี S3 Bucket เหมือนกับบทความก่อนหน้านี้เพื่อใช้เป็นพื้นที่เก็บข้อมูลสำหรับนำมาแสดงใน Amazon Data Firehose โดยผมจะกำหนดชื่อ S3 Bucket ตามตัวอย่างด้านล่างนี้

ครั้งนี้จะใช้ชื่อ S3 Bucket ดังนี้
・Bucket name: tinnakorn-test-s3 (ครั้งนี้สร้างไว้ใน Region Singapore)

สามารถดูตัวอย่างได้ที่ลิงก์ด้านล่างนี้
การสร้าง Buckets ใน Amazon S3

สร้าง Amazon Data Firehose

ครั้งนี้จะดำเนินการใน Region Singapore

ให้ค้นหาและคลิก Amazon Data Firehose
service_firehose-search

แล้วคลิก Create Firehose stream
button_create_amazon_data_firehose

แล้วจะตั้งค่าดังนี้
Choose source and destination
・Source: Direct PUT
・Destination: Amazon S3 (หลังจากเลือกนี้แล้ว หัวข้อ "Firehose stream name" จะแสดงขึ้นมาด้านล่างอัตโนมัติ)

Firehose stream name
・Firehose stream name: tinnakorn-test-firehose
create_amazon_data_firehose-2

ต่อไปหัวข้อ Destination settings
คลิก Browse แล้วเลือก S3 bucket เช่น tinnakorn-test-s3 (เลือก S3 bucket ที่สร้างก่อนหน้านี้)
create_amazon_data_firehose-3

แล้วเลื่อนลงมาด้านล่างที่หัวข้อ Buffer hints, compression, file extension and encryption แล้วคลิกเพื่อขยายฟังก์ชันการตั้งค่าต่างๆด้านล่าง โดยครั้งนี้จะตั้งค่า "Buffer interval: 120 seconds" แล้วคลิก Create Firehose stream ที่ด้านล่างสุด
create_amazon_data_firehose_set120

สร้าง IAM Role

การสร้าง IAM Role ครั้งนี้จะเป็นการเพิ่ม Permission ให้กับ EC2 สามารถเข้าถึง Amazon Data Firehose ได้ โดยในบทความนี้จะใช้ Permission และชื่อ Role ดังนี้
・Permissions policies (Policy name): AmazonKinesisFirehoseFullAccess
・Role name: tinnakorn-test-firehose-role

ดูตัวอย่างการสร้าง IAM Role ได้ที่ลิงก์ด้านล่างนี้ (แนะนำให้ดู การสร้าง IAM Role สำหรับบทความนี้ ไปด้วย)
การสร้าง IAM Role

การสร้าง IAM Role สำหรับบทความนี้

วิธีการสร้างจะเหมือนกับลิงก์ด้านบนนี้ แต่มีการตั้งค่าบางส่วนที่แตกต่างกันเล็กน้อยดังนี้

Step 1 - Select trusted entity

Trusted entity type
・เลือก AWS service

Use case
・เลือก ◉ EC2
・คลิก Next
create_iam_ec2_firehose-1

Step 2 - Add permissions

・ค้นหา Permissions policies: AmazonKinesisFirehoseFullAccess
・ติ๊ก AmazonKinesisFirehoseFullAccess
・คลิก Next
create_iam_ec2_firehose-2

Step 3 - Name, review, and create

ป้อนชื่อในช่อง Role name ตามต้องการ (ครั้งนี้จะใช้ชื่อ tinnakorn-test-firehose-role) แล้วคลิก Create role ด้านล่างสุด ก็จะเสร็จสิ้นในขั้นตอนนี้

สร้าง EC2 Instance

ทำการติดตั้ง EC2 Instance สำหรับใช้ในการเชื่อมต่อกับ Firehose โดยทำตามลิงก์ด้านล่างนี้
วิธีติดตั้ง Amazon Linux 2023 บน EC2 และเชื่อมต่อเซิร์ฟเวอร์ด้วยโปรแกรม PuTTY

※ตัวอย่างตั้งค่าการสร้าง EC2 Instance ในบทความนี้
Create Key pairs
Key pairs: tinnakorn-test-firehose-ec2

Launch instances
Name and tags
Name: tinnakorn-test-firehose-ec2

Application and OS Images (Amazon Machine Image)
Amazon Machine Image (AMI): Amazon Linux 2023 AMI (Default)

Instance type
Instance type: t3a.micro

Key pair (login)
Key pair name - required: tinnakorn-test-firehose-ec2

Network settings
Firewall (security groups)
Security group name - required: tinnakorn-test-firehose-ec2
Description - required: tinnakorn-test-firehose-ec2

Inbound security groups rules
Security group rule 1 (TCP, 22, 0.0.0.0/0)
Type: ssh ▼ | Source type: My IP ▼ | Source: xxx.xxx.x.xxx/32 ✕

Configure storage
1x: 8 GiB gp3 ▼ Root volume (Default)

Advanced details
**หลังจากนี้จะเป็นเนื้อหาที่เพิ่มเติมจากการตั้งค่าตามลิงก์ด้านบน**
IAM Instance profile: เลือก IAM Role ที่เราสร้างก่อนหน้านี้ (ครั้งนี้คือ tinnakorn-test-firehose-role)
add_iam_role_ec2

เมื่อสร้าง Instance เสร็จแล้วให้รันคำสั่งในโปรแกรม PuTTY ในขั้นตอนถัดไป

รันคำสั่งใน PuTTY

สำหรับการเชื่อมต่อ EC2 Instance ด้วย PuTTY ดูที่ลิงก์ด้านล่างนี้
การเชื่อมต่อกับ EC2 Instance ด้วย PuTTY

เมื่อเชื่อมต่อเข้ามาได้แล้วให้รันคำสั่งใช้งานสิทธิ์ root ตามด้านล่างนี้

sudo su -

แล้วรันคำสั่ง Update server ให้เป็นปัจจุบันเสมอ

yum update -y

เปลี่ยน Time Zone EC2

รันคำสั่งนี้เพื่อเปลี่ยนเวลาจาก UTC ให้เป็น +07

timedatectl set-timezone Asia/Bangkok
date

Output
จะเห็นว่าเวลาปัจจุบันเป็น +07 เรียบร้อยแล้ว (หากตรวจสอบเวลาปัจจุบันด้วย date ในตอนแรกจะแสดงเป็นเขตเวลา UTC)

[root@ip-xx-xx-xx-xx ~]# timedatectl set-timezone Asia/Bangkok
date
Thu Jan  2 12:20:07 +07 2025
[root@ip-xx-xx-xx-xx ~]#

ต่อไปตรวจสอบเวอร์ชัน Python ว่าตอนนี้มีอยู่ในเซิร์ฟเวอร์หรือไม่

python3 --version

Output

[root@ip-xx-xx-xx-xx ~]# python3 --version
Python 3.9.20
[root@ip-xx-xx-xx-xx ~]#

ดูข้อมูลเพิ่มเติมเกี่ยวกับ Time Zone ได้ที่ลิงก์ด้านล่างนี้
วิธีตั้งค่า Time Zone ใน Amazon Linux 2 ของ EC2

ติดตั้ง PIP

รันคำสั่งติดตั้งแพ็กเกจ python3-pip

yum install python3-pip -y

รันคำสั่งตรวจสอบเวอร์ชันของ PIP ที่ติดตั้งอยู่ในระบบของเรา

pip3 --version

Output

[root@ip-xx-xx-xx-xx ~]# pip3 --version
pip 21.3.1 from /usr/lib/python3.9/site-packages/pip (python 3.9)
[root@ip-xx-xx-xx-xx ~]#

แล้วติดตั้ง PIP (Package Installer for Python)
*boto3 คือ AWS SDK ที่ใช้งานสำหรับ Python โดยเฉพาะทำให้ง่ายต่อการทำงานร่วมกันของโค้ดหรือโปรแกรมที่เขียนด้วย Python

pip3 install boto3

Output

[root@ip-xx-xx-xx-xx ~]# pip3 install boto3
Collecting boto3
  Downloading boto3-1.35.90-py3-none-any.whl (139 kB)
     |████████████████████████████████| 139 kB 3.5 MB/s
Collecting botocore<1.36.0,>=1.35.90
  Downloading botocore-1.35.90-py3-none-any.whl (13.3 MB)
     |████████████████████████████████| 13.3 MB 27.5 MB/s
Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in /usr/lib/python3.9/site-packages (from boto3) (0.10.0)
Collecting s3transfer<0.11.0,>=0.10.0
  Downloading s3transfer-0.10.4-py3-none-any.whl (83 kB)
     |████████████████████████████████| 83 kB 3.2 MB/s
Requirement already satisfied: urllib3<1.27,>=1.25.4 in /usr/lib/python3.9/site-packages (from botocore<1.36.0,>=1.35.90->boto3) (1.25.10)
Requirement already satisfied: python-dateutil<3.0.0,>=2.1 in /usr/lib/python3.9/site-packages (from botocore<1.36.0,>=1.35.90->boto3) (2.8.1)
Requirement already satisfied: six>=1.5 in /usr/lib/python3.9/site-packages (from python-dateutil<3.0.0,>=2.1->botocore<1.36.0,>=1.35.90->boto3) (1.15.0)
Installing collected packages: botocore, s3transfer, boto3
Successfully installed boto3-1.35.90 botocore-1.35.90 s3transfer-0.10.4
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
[root@ip-xx-xx-xx-xx ~]#

ในขั้นตอนถัดไปให้ Upload โค้ด Python ตามที่ทางเราสร้างขึ้นมาเพื่อทดสอบการส่งข้อมูลไปยัง Firehose

สร้างโปรแกรมทดสอบการส่งข้อมูลไปยัง Firehose

รันคำสั่งย้ายไปยัง /root (หากทำตามขั้นตอนนี้ทั้งหมดจะอยู่ใน /root อยู่แล้ว)
*หากต้องการตรวจสอบ path ปัจจุบันให้ใช้คำสั่ง pwd

cd ~/

แล้วรันคำสั่ง Upload โค้ด Python ที่ทางเราสร้างขึ้นไว้ลงในเซิร์ฟเวอร์ Instance นี้ของเรา

wget https://raw.githubusercontent.com/classmethod-thailand/cmth_seminar/develop/iot_core_webinar/create_sample_json_to_firehose2.py

รันคำสั่งเปลี่ยนแปลงสิทธิ์การเข้าถึงของไฟล์ (chmod 777 + file_name)

chmod 777 create_sample_json_to_firehose2.py

แล้วรันคำสั่งแก้ไขไฟล์ (vi + file_name)

vi create_sample_json_to_firehose2.py

ทีนี้เรามาแก้ไขไฟล์ดังนี้
» กดปุ่ม i ที่แป้นพิมพ์ ให้ "create_sample_json_to_firehose2.py" 26L, 602B ที่อยู่ด้านล่างซ้ายเปลี่ยนเป็น --INSERT--
» แล้วแก้ไขไฟล์โดยเปลี่ยน firehose_stream_name ให้เป็นชื่อ Firehose streams ของเรา เช่น tinnakorn-test-firehose
» แล้วกดปุ่ม Esc ให้คำว่า -- INSERT -- หายไป และพิมพ์ :x + Enter เพื่อบันทึกและออกจากไฟล์
Output

import json
import datetime
import random
import math
import boto3

firehose_stream_name = "tinnakorn-test-firehose"

hour = datetime.datetime.now().hour
a1 = math.sin(hour * math.pi / 24) + 1
dist = random.lognormvariate(a1, a1 / 3)
if dist <= 0.1:
    dist = 0.1

json_obj = {
    "timestamp": datetime.datetime.now().timestamp(),
    "payloads":{
        "distance": dist,
    }
}
send_data = (json.dumps(json_obj) + "\n").encode()

client = boto3.client('firehose', region_name='ap-southeast-1')
response = client.put_record(
    DeliveryStreamName = firehose_stream_name,
    Record = {"Data": send_data})
~
~
:x

ต่อไปรันคำสั่งนี้เพื่ออัปโหลดไฟล์ JSON ไปยัง Amazon S3 แล้วรอประมาณ 120 วินาทีตามที่ได้ตั้งค่า Buffer interval ไว้

python3 create_sample_json_to_firehose2.py

เมื่อผ่านไป 120 วินาทีแล้ว เข้าไปที่บริการ Amazon S3 แล้วคลิกเข้าไปที่โฟลเดอร์ด้านในสุดจะเห็นไฟล์ที่ถูกอัปโหลดเข้ามาแสดงอยู่ที่นี่ ก็ให้ติ๊ก ✅️ แล้วคลิก Download ไฟล์ลงอุปกรณ์ของเรา
upload_json_file_to_s3_firehose-1

แล้วเปิดไฟล์เพื่อดูข้อมูลที่อยู่ในไฟล์เหล่านี้ ก็จะเห็นข้อมูลที่เป็น "distance" และ "datetime" แบบนี้
upload_json_file_to_s3_firehose-2

แต่ในตอนนี้ระบบยังไม่สามารถ Upload ข้อมูลได้อัตโนมัติ เราต้องรันคำสั่งทุกครั้งเมื่อต้องการจะ Upload ข้อมูลใหม่เข้าไปยัง Amazon S3 ดังนั้นก็ให้ตั้งค่าระบบให้สามารถส่งข้อมูลเข้าไปยัง S3 Bucket ได้อัตโนมัติในขั้นตอนถัดไป

การใช้งาน cron สำหรับ Amazon Linux 2023

ติดตั้ง cron สำหรับ Amazon Linux 2023

ก่อนอื่นให้ติดตั้ง cronie ก่อน เนื่องจากใน Amazon Linux 2023 ต้องติดตั้งเอง
*หากไม่ติดตั้ง cronie สำหรับ Amazon Linux 2023 ก็จะไม่สามารถใช้งาน cron ให้ทำงานในรูปแบบอัตโนมัติได้

รันคำสั่งติดตั้ง cronie

yum install -y cronie
systemctl enable --now crond

ดูข้อมูลเพิ่มเติมได้ที่ลิงก์ด้านล่างนี้
systemd timers replace cron - Amazon Linux 2023
Automate letsEncrypt SSL cert for Lightsail AL2023 | AWS re:Post

แล้วจะรันคำสั่งตรวจสอบการทำงานของไฟล์ crontab ในขั้นตอนถัดไป ดังนั้นตอนนี้จะยังไม่รันคำสั่งนี้

journalctl -efu crond

ตั้งค่า crontab ใน Amazon Linux 2023

ขั้นตอนต่อไปจะเป็นการแก้ไขไฟล์ crontab เพื่อที่จะทำให้ระบบ Firehose สามารถอัปส่งข้อมูลไปยัง S3 ได้โดยอัตโนมัติ

เข้ามาที่หน้าจอ Terminal แล้วรันคำสั่งนี้เพื่อเข้ามาที่ไฟล์ crontab และเพิ่ม Code ในขั้นตอนถัดไป

vi /etc/crontab

ทีนี้เรามาแก้ไขไฟล์ crontab โดยการเพิ่ม Code ตามนี้
» กดปุ่ม i ให้คำว่า "/etc/crontab" 15L, 451B ที่อยู่ด้านล่างซ้ายเปลี่ยนเป็น -- INSERT --
» Copy Code ด้านล่างนี้ และนำไปวางที่บรรทัดถัดไปของ # * * * * * user-name command to be executed

* * * * * root /usr/bin/python3 /root/create_sample_json_to_firehose2.py

» แล้วกดปุ่ม Esc ให้คำว่า -- INSERT -- หายไป และพิมพ์ :x + Enter เพื่อบันทึกและออกจากไฟล์
Output

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
* * * * * root /usr/bin/python3 /root/create_sample_json_to_firehose2.py
~
~
:x

ตรวจสอบการทำงานของไฟล์ crontab

หลังจากตั้งค่า cron เสร็จแล้ว ให้รันคำสั่งตรวจสอบการทำงานของไฟล์ crontab โดยหลังจากนี้ไฟล์ JSON ก็จะถูกสร้างและอัปโหลดไปที่ S3 เรื่อยๆ ทุกๆ "3 นาที/1 ไฟล์" แต่ผมต้องการอัปโหลด 2 ไฟล์ดังนั้นจะรอ 6 นาที

สำหรับเวลา 6 นาทีจะแบ่งเป็นดังนี้
・Firehose streams = 2 นาที (120 seconds) ตามที่ตั้งค่าใน Buffer interval
・crontab = 1 นาที (60 seconds)
・รวมแล้วได้ "3 นาที/1 ไฟล์" โดยในตัวอย่างนี้ผมต้องการอัปโหลด 2 ไฟล์ ก็จะต้องรอ 6 นาที

*หากยังไม่ติดตั้ง ติดตั้ง cron สำหรับ Amazon Linux 2023 จะไม่สามารถรันคำสั่งนี้ได้)

journalctl -efu crond

เมื่อครบ 6 นาทีแล้ว จะเปลี่ยนเป็นแบบนี้โดยให้สังเกตเวลาปัจจุบัน เช่น Jan 02 12:54:02
Output

[root@ip-xx-xx-xx-xx ~]# journalctl -efu crond
Jan 02 12:46:32 ip-172-31-11-23.ap-southeast-1.compute.internal systemd[1]: Started crond.service - Command Scheduler.
Jan 02 12:46:33 ip-172-31-11-23.ap-southeast-1.compute.internal crond[7384]: (CRON) STARTUP (1.5.7)
Jan 02 12:46:33 ip-172-31-11-23.ap-southeast-1.compute.internal crond[7384]: (CRON) INFO (Syslog will be used instead of sendmail.)
Jan 02 12:46:33 ip-172-31-11-23.ap-southeast-1.compute.internal crond[7384]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 6% if used.)
Jan 02 12:46:33 ip-172-31-11-23.ap-southeast-1.compute.internal crond[7384]: (CRON) INFO (running with inotify support)
Jan 02 12:49:01 ip-172-31-11-23.ap-southeast-1.compute.internal crond[7384]: (*system*) RELOAD (/etc/crontab)
Jan 02 12:49:01 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26439]: (root) CMD (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:49:01 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26438]: (root) CMDEND (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:50:01 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26442]: (root) CMD (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:50:02 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26441]: (root) CMDEND (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:51:01 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26508]: (root) CMD (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:51:01 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26507]: (root) CMDEND (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:52:01 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26569]: (root) CMD (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:52:02 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26568]: (root) CMDEND (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:53:01 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26571]: (root) CMD (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:53:02 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26570]: (root) CMDEND (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:54:02 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26632]: (root) CMD (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)
Jan 02 12:54:02 ip-172-31-11-23.ap-southeast-1.compute.internal CROND[26631]: (root) CMDEND (/usr/bin/python3 /root/create_sample_json_to_firehose2.py)

เข้ามาที่ S3 Bucket จะเห็นว่ามีไฟล์ JSON เพิ่มขึ้นมา 3 ไฟล์โดยอัตโนมัติ
upload_json_file_to_s3_firehose-3

เพียงเท่านี้ก็เสร็จสิ้นการตั้งค่าและใช้งานการส่งข้อมูลจาก EC2 ไปยัง Firehose แล้วครับ

ลบ Resource

หากเราไม่ต้องการใช้งานแล้วก็ควรจะลบ Resource เพื่อประหยัดค่าใช้จ่ายโดยดูวิธีการลบในหัวข้อนี้ได้เลย

  • EC2
    • Instances
    • Key pairs
    • Security Groups
  • Amazon Data Firehose
    • Firehose streams
  • Identity and Access Management (IAM)
    • Roles
  • Amazon S3
    • Buckets

ลบ Firehose stream ใน Amazon Data Firehose

ดูตัวอย่างที่นี่เฉพาะหัวข้อนี้: ลบ Firehose stream ใน Amazon Data Firehose

ลบ Role ใน Identity and Access Management (IAM)

ดูตัวอย่างที่นี่เฉพาะหัวข้อนี้: ลบ Role ใน Identity and Access Management (IAM)

ลบ Bucket ใน Amazon S3

ดูตัวอย่างที่นี่เฉพาะหัวข้อนี้: ลบ Bucket ใน Amazon S3

การ Terminate Instance, ลบ Key Pair และลบ Security Group ใน EC2

ดูวิธีการลบ Resource ใน EC2 เช่น Instance, Key Pair และ Security Group ได้ที่ลิงก์ด้านล่างนี้
การ Terminate Instance, ลบ Key Pair และลบ Security Group ใน EC2

บทความที่เกี่ยวข้อง

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.